package com.juyu.miliao.api.controller;

import com.juyu.miliao.api.exception.*;
import com.juyu.miliao.common.exception.*;
import com.juyu.miliao.common.msg.CommonErrorMsgs;
import com.juyu.miliao.common.msg.ErrorMsg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.nio.file.AccessDeniedException;

@RestControllerAdvice
@Slf4j
public class ExceptionHandlers implements CommonErrorMsgs {

    @ExceptionHandler({Exception.class})
    public ResponseEntity<?> handleIllegalException(Exception ex){
        log.error("Exception log：AllinFormation");
        log.error(ex.getClass().getName());
        log.error(getExceptionAllinFormation(ex));
        return new ResponseEntity<>(ex.toString(), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    public static String getExceptionAllinFormation(Exception ex){
        String sOut = "";
        StackTraceElement[] trace = ex.getStackTrace();
        for (StackTraceElement s : trace) {
            sOut += "\tat " + s + "\r\n";
        }
        return sOut;
    }

    @ExceptionHandler({BindException.class, IllegalParamException.class})
    public Object handleIllegalParamException(Exception ex)
            throws Exception {
        return new ResponseEntity<ErrorMsg>(ILLEGAL_PARAM, ILLEGAL_PARAM.getStatus());
    }

    @ExceptionHandler({AccessDeniedException.class, NoPermissionException.class})
    public ResponseEntity<?> handleNoPermissionException(Exception ex) {
        return new ResponseEntity<ErrorMsg>(NO_PERMISSION, NO_PERMISSION.getStatus());
    }

    @ExceptionHandler({WrongNoDepositException.class})
    public ResponseEntity<?> handleWrongNoDepositException(WrongNoDepositException ex)
            throws Exception {
        return new ResponseEntity<ErrorMsg>(No_DEPOSIT, No_DEPOSIT.getStatus());
    }

    @ExceptionHandler({WrongErrorWeek.class})
    public ResponseEntity<?> handleWrongErrorWeek(WrongErrorWeek ex)
            throws Exception {
        return new ResponseEntity<ErrorMsg>(ERROR_WEEK, ERROR_WEEK.getStatus());
    }

    @ExceptionHandler({WrongErrorMoney.class})
    public ResponseEntity<?> handleWrongErrorMoney(WrongErrorMoney ex)
            throws Exception {
        return new ResponseEntity<ErrorMsg>(ERROR_MONEY, ERROR_MONEY.getStatus());
    }

    @ExceptionHandler({WrongErrorRepeat.class})
    public ResponseEntity<?> handleWrongErrorRepeat(WrongErrorRepeat ex)
            throws Exception {
        return new ResponseEntity<ErrorMsg>(ERROR_REPEAT, ERROR_REPEAT.getStatus());
    }

    @ExceptionHandler({WrongErrorShare.class})
    public ResponseEntity<?> handleWrongErrorShare(WrongErrorShare ex)
            throws Exception {
        return new ResponseEntity<ErrorMsg>(ERROR_SHARE, ERROR_SHARE.getStatus());
    }

    @ExceptionHandler({WrongErrorShareUserId.class})
    public ResponseEntity<?> handleWrongErrorShareUserId(WrongErrorShareUserId ex)
            throws Exception {
        return new ResponseEntity<ErrorMsg>(ERROR_SHAREUSERID, ERROR_SHAREUSERID.getStatus());
    }

    @ExceptionHandler({WrongErrorUserNoOnePay.class})
    public ResponseEntity<?> handleWrongErrorUserNoOnePay(WrongErrorUserNoOnePay ex)
            throws Exception {
        return new ResponseEntity<ErrorMsg>(ERROR_USER_NOONE_PAY, ERROR_USER_NOONE_PAY.getStatus());
    }

    @ExceptionHandler({WrongNickNameException.class})
    public ResponseEntity<?> handleWrongNickNameException(WrongNickNameException ex)
            throws Exception {
        return new ResponseEntity<ErrorMsg>(ERROR_NICK_NAME, ERROR_NICK_NAME.getStatus());
    }

    @ExceptionHandler({DataValidateException.class})
    public ResponseEntity<?> handleDataValidateException(DataValidateException ex)
            throws Exception {
        return new ResponseEntity<>(new ErrorMsg(HttpStatus.BAD_REQUEST, "20000", ex.getMessage()), HttpStatus.BAD_REQUEST);
    }


    @ExceptionHandler({ConsumeRuntimeException.class})
    public ResponseEntity<?> handleConsumeRuntimeExceptionException(ConsumeRuntimeException ex)
            throws Exception {
        return new ResponseEntity<>(ex.getErrorMsg(), ex.getErrorMsg().getStatus());
    }

    @ExceptionHandler({SecretLanguagePlanetException.class})
    public ResponseEntity<?> handleSecretLanguagePlanetException(SecretLanguagePlanetException ex)
            throws Exception {
        return new ResponseEntity<>(ex.getErrorMsg(), ex.getErrorMsg().getStatus());
    }

    @ExceptionHandler({SignInException.class})
    public ResponseEntity<ErrorMsg> handleSignInException(SignInException ex) {
        return new ResponseEntity<>(ERROR_SIGN_IN, ERROR_SIGN_IN.getStatus());
    }

    @ExceptionHandler({VipSignInRewardException.class})
    public ResponseEntity<ErrorMsg> handleVipSignInRewardException(VipSignInRewardException ex) {
        return new ResponseEntity<>(ERROR_VIP_SIGN_IN_REWARD, ERROR_VIP_SIGN_IN_REWARD.getStatus());
    }

    @ExceptionHandler({NotVipException.class})
    public ResponseEntity<ErrorMsg> handleNotVipException(NotVipException ex) {
        return new ResponseEntity<>(NOT_VIP, NOT_VIP.getStatus());
    }

}
